<template>
  <div>
    <h1 class="seo-title">Base64转图片 - 在线Base64转换工具</h1>
    <div class="tool-bar">
      <button class="bar-btn" @click="toPic">Base64转图片</button>
      <button class="bar-btn" @click="toPdf">Base64转PDF</button>
    </div>

    <div class="text-content">
      <Codemirror
        class="input-editor"
        v-model:value="origin"
        border
        height="560"
        width="640"
        :options="cmRef"
      >
      </Codemirror>
      <div class="right-image">
        <span>{{ info }}</span>
        <img v-if="pic" :src="basePic" width="600">
        <embed v-if="!pic" :src="basePdf" width="640" height="100%" />
      </div>
    </div>
  </div>
</template>

<script>
import "codemirror/mode/javascript/javascript.js"
import "codemirror/mode/xml/xml.js"
import Codemirror from "codemirror-editor-vue3"
import { useHead } from '@vueuse/head'

export default {
  components: { Codemirror },
  data () {
    return {
      origin: "",
      basePic: "",
      basePdf: "",
      pic: true,
      info: "",
      cmRef: {
        mode: "application/json",
        lineWrapping: true
      }
    }
  },
  setup() {

  },
  methods: {
    toPdf() {
      this.event('toPdf')
      this.info = ""
      if (this.origin === '') {
        this.info = ""
        this.basePdf = ""
        return
      }
      this.basePdf = 'data:application/pdf;base64,' + this.origin
      this.pic = false
    },
    toPic() {
      this.event('toPic')
      this.info = ""
      if (this.origin === '') {
        this.info = ""
        this.basePic = ""
        return
      }
      this.getBase64ImageSize(this.origin)
      this.pic = true
    },
    inferImageFormat(base64Data) {
      var byteCharacters = atob(base64Data);
      var byteNumbers = new Array(byteCharacters.length);
      for (var i = 0; i < byteCharacters.length; i++) {
          byteNumbers[i] = byteCharacters.charCodeAt(i);
      }

      var byteArray = new Uint8Array(byteNumbers);
      if (byteArray[0] === 0xFF && byteArray[1] === 0xD8) {
          return 'jpeg';
      } else if (byteArray[0] === 0x89 && byteArray[1] === 0x50 && byteArray[2] === 0x4E && byteArray[3] === 0x47) {
          return 'png';
      } else if (byteArray[0] === 0x47 && byteArray[1] === 0x49 && byteArray[2] === 0x46) {
          return 'gif';
      } else {
          return 'unknown';
      }
    },
    getBase64ImageSize(base64String) {
      // 移除可能存在的任何前缀
      base64String = base64String.replace(/^data:image\/(png|jpeg|jpg);base64,/, '');

      try {
        atob(base64String)
      } catch (error) {
        this.info = "解码失败，请确认base64格式是否正确"
        return
      }

      // 推断图片格式
      var format = this.inferImageFormat(base64String);

      // 将Base64字符串转换为二进制数据
      var binary = atob(base64String);
      var array = [];
      for (var i = 0; i < binary.length; i++) {
          array.push(binary.charCodeAt(i));
      }
      var blob = new Blob([new Uint8Array(array)], {type: 'image/' + format});

      // 创建一个指向该Blob的URL
      var imgURL = URL.createObjectURL(blob);

      // 创建一个<img>元素
      var img = new Image();
      let that = this
      img.onload = function() {
          that.info = "图片格式: " + format + ", widht: " + img.width + ", height: " + img.height
          URL.revokeObjectURL(imgURL);
          that.basePic = 'data:image/'+format+';base64,' + base64String;
      };

      img.onerror = function() {
        that.info = "图片格式错误无法解析"
      };
      img.src = imgURL;
    },
    event(act) {
      try {
        LA.track(act);
      } catch (e) {
        console.log(e)
      }
    }
  }
}
</script>
  
<style scoped>
.tool-bar { 
  text-align: left;
  margin: 2px auto;
  width: 1324px;
}

.bar-btn {
  margin-right: 4px;
  color: #333;
}

.text-content {
  display: flex;
  justify-content: center;
  align-items: center;
}
.right-image {
  width: 660px;
  height: 560px;
  margin: 4px 4px 4px 18px;
}

.seo-title {
  position: absolute;
  width: 1px;
  height: 1px;
  padding: 0;
  margin: -1px;
  overflow: hidden;
  clip: rect(0, 0, 0, 0);
  white-space: nowrap;
  border: 0;
}
</style>
